import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:gameplay_flutter/lib_baseview/theme/jr.dart';
import 'package:gameplay_flutter/lib_runtime/extension/string_extension/string_text.dart';
import 'package:gameplay_flutter/lib_runtime/extension/widget/widget_wrapper.dart';
import 'package:gameplay_flutter/resource/language/generated/l10n.dart';

class VeriInputCodeWidget extends StatefulWidget {
  final int count;

  /// 输入的验证码
  final String code;
  final Function(String code) onResult;
  final Future<bool> Function() onRestart;

  const VeriInputCodeWidget({
    super.key,
    required this.count,
    required this.code,
    required this.onResult,
    required this.onRestart,
  });

  @override
  State createState() => _VeriInputCodeWidgetState();
}

class _VeriInputCodeWidgetState extends State<VeriInputCodeWidget>
    with WidgetsBindingObserver, TickerProviderStateMixin {
  late final ValueNotifier<String> code = ValueNotifier('');
  late TextEditingController _textController = TextEditingController();
  late FocusNode inputFocus = FocusNode()..addListener(() => setState(() {}));
  late AnimationController _cursorController;

  bool restart = false;
  Timer? timer;
  final int seconds = 60;
  late final ValueNotifier<int> timeCount = ValueNotifier(seconds);
  DateTime? pausedTime;

  @override
  void initState() {
    super.initState();
    code.addListener(_handleCodeChange);
    _cursorController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    )..repeat(reverse: true);

    WidgetsBinding.instance.addObserver(this);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      inputFocus.requestFocus();
      startTimer();
    });

    code.value = widget.code;
  }

  void _handleCodeChange() {
    if (_textController.text != code.value) {
      _textController.text = code.value;
    }
  }

  void startTimer() {
    timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      timeCount.value--;
      if (timeCount.value <= 0) {
        timer.cancel();
        code.value = '';
        timeCount.value = seconds;
        setState(() => restart = true);
      }
    });
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed && pausedTime != null) {
      final diff = DateTime.now().difference(pausedTime!).inSeconds;
      timeCount.value = max(0, timeCount.value - diff);
      startTimer();
      pausedTime = null;
    } else if (state == AppLifecycleState.paused) {
      timer?.cancel();
      pausedTime = DateTime.now();
    }
  }

  @override
  void dispose() {
    code.removeListener(_handleCodeChange);
    _textController.dispose();
    _cursorController.dispose();
    WidgetsBinding.instance.removeObserver(this);
    timer?.cancel();
    super.dispose();
  }

  Widget buildCodeInput() {
    return SizedBox(
      height: 0,
      width: 0,
      child: TextField(
        controller: _textController,
        focusNode: inputFocus,
        maxLength: widget.count,
        keyboardType: TextInputType.number,
        cursorRadius: const Radius.circular(1),
        enableInteractiveSelection: false,
        decoration: const InputDecoration(
          counterText: '',
          border: OutlineInputBorder(borderSide: BorderSide.none),
        ),
        inputFormatters: [
          FilteringTextInputFormatter(RegExp(r"^\d*"), allow: true)
        ],
        onChanged: (v) {
          code.value = v;
          // if (v.length == widget.count) widget.onResult(v);
          widget.onResult(v);
        },
      ),
    );
  }

  Widget buildCodeView() {
    return ValueListenableBuilder<String>(
      valueListenable: code,
      builder: (context, value, _) {
        return GridView.count(
          padding: EdgeInsets.zero,
          crossAxisCount: widget.count,
          mainAxisSpacing: 8,
          crossAxisSpacing: 24,
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          childAspectRatio: 0.9,
          children: List.generate(widget.count, (index) {
            final showCursor = index == value.length &&
                inputFocus.hasFocus &&
                value.length < widget.count;

            return Stack(
              alignment: Alignment.center,
              children: [
                Container(
                  width: 48,
                  height: 48,
                  decoration: BoxDecoration(
                    color: const Color(0xFFFAFAFA),
                    borderRadius: BorderRadius.circular(4),
                  ),
                  child: value.length > index
                      ? Center(
                          child: Text(
                            value[index],
                            style: const TextStyle(
                                fontSize: 24,
                                fontWeight: FontWeight.w600,
                                color: Colors.black),
                            textAlign: TextAlign.center,
                          ),
                        )
                      : null,
                ),
                if (showCursor)
                  AnimatedBuilder(
                    animation: _cursorController,
                    builder: (_, __) => Opacity(
                      opacity: _cursorController.value,
                      child: Container(
                        width: 2,
                        height: 32,
                        color: Colors.blue,
                      ),
                    ),
                  ),
              ],
            );
          }),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    double startWidget = 15;
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: [
        const SizedBox(height: 32),
        buildCodeInput(),
        GestureDetector(
          onTap: () {
            inputFocus.requestFocus();
            SystemChannels.textInput.invokeMethod('TextInput.show');
          },
          child: buildCodeView(),
        ),
        const SizedBox(height: 10),
        if (!restart)
          ValueListenableBuilder<int>(
            valueListenable: timeCount,
            builder: (context, value, child) {
              return Row(
                children: [
                  '${value}s '.text(
                      color: const Color(0xFFA8A8A8),
                      fontSize: 12,
                      weight: TextFontWeight.medium),
                  T.current.login_send_reset.text(
                    color: const Color(0xFFA8A8A8),
                    fontSize: 12,
                  ),
                ],
              );
            },
          ).padding(start: startWidget),
        if (restart)
          GestureDetector(
            onTap: () async {
              if (await widget.onRestart.call()) {
                setState(() {
                  restart = false;
                });
                startTimer();
              }
            },
            child: Row(
              children: [
                T.current.login_send_reset2.text(
                    color: const Color(0xFF7091FF),
                    fontSize: 12,
                    weight: TextFontWeight.medium),
                JR.img('login/login_send_reset.png', width: 14, height: 14),
              ],
            ),
          ).padding(start: startWidget),
      ],
    );
  }
}
